/**
 * Created by public on 2017/12/8.
 */
(function (root, factory, pluginName) {
    factory(root.jQuery, pluginName);
})(window, function ($, pluginName) {
    var _PROTOTYPE_ = {
        _init: function () {
            this.$dndArea = $("#dndArea");
            this.$queueList = $(this).find('.queueList');
            this.$queue = $('<ul class="filelist"></ul>').appendTo(this.$queueList);
            this.$statusBar = $(this).find('.statusBar');
            this.$info = this.$statusBar.find('.info');
            this.$upload = this.find('.uploadBtn');
            this.$placeHolder = $(this).find('.placeholder');
            this.$progress = this.$statusBar.find('.progress').hide();
            this.is_moveing = false;
            this.fileCount = 0;
            this.fileSize = 0;
            this.state = 'pedding';
            this.percentages = {};
            this.supportTransition = (function () {
                var s = document.createElement('p').style,
                    r = 'transition' in s ||
                        'WebkitTransition' in s ||
                        'MozTransition' in s ||
                        'msTransition' in s ||
                        'OTransition' in s;
                s = null;
                return r;
            })();
            this.ratio = window.devicePixelRatio || 1;
            this.thumbnailWidth = this.thumbWidth || 110;
            this.thumbnailWidth *= this.ratio;
            this.thumbnailHeight = this.thumbHeight || 110;
            this.thumbnailHeight *= this.ratio;
            this.uploader = WebUploader.create({
                                                   auto: true,
                                                   swf: "webuploader-0.1.5/Uploader.swf",
                                                   server: this.uploadUrl,
                                                   fileSizeLimit: this.allMaxNum * this.allMaxSize
                                                                        * 1024 * 1024,//限制上传所有文件大小
                                                   fileSingleSizeLimit: this.allMaxSize * 1024
                                                                        * 1024,//限制上传单个文件大小
                                                   pick: {
                                                       id: '#filePicker',
                                                       label: '点击选择图片'
                                                   },
                                                   formData: {
                                                       "noticeId": this._getUrlParams("noticeId"),
                                                       "noticeType": this._getUrlParams("noticeType")
                                                   },
                                                   dnd: '.queueList',
                                                   paste: document.body,
                                                   accept: {
                                                       title: 'Images',
                                                       extensions: 'gif,jpg,jpeg,png',
                                                       mimeTypes: 'images/*'
                                                   },
                                                   compress: null,
                                                   resize: false,
                                                   disableGlobalDnd: true,
                                                   chunked: true,
                                                   fileNumLimit: this.allMaxNum,
                                                   fileSizeLimit:       this.allMaxNum
                                                                        * this.allMaxSize * 1024
                                                                        * 1024,//限制上传所有文件大小
                                                   fileSingleSizeLimit: this.allMaxSize * 1024
                                                                        * 1024,//限制上传单个文件大小
                                               });
            if (!WebUploader.Uploader.support()) {
                console.log('WebUploader 不支持');
                throw new Error('WebUploader does not support');
            }
            this.uploader.addButton({
                                        id: '#filePicker2',
                                        label: '继续添加'
                                    });
            this._initServerFile();
            this._error();
            this._uploadProgress();
            this._fileQueued();
            this._fileDequeued();
            this._uploadSuccess();
            this._uploadError();
            this._uploadComplete();
            this._uploadAll();
            this._uploadBeforeSend();
            this._retryBind();
            this._ignoreBind();
            this.$upload.addClass('state-' + this.state);
            this._updateTotalProgress();

        },
        _retryBind: function () {
            var _this = this;
            this.$info.on('click', '.retry', function () {
                _this.uploader.retry();
            });
        },
        _ignoreBind: function () {
            this.$info.on('click', '.ignore', function () {
                console.log('todo');
            });
        },
        _fileQueued: function () {
            var _this = this;
            this.uploader.on('fileQueued', _this._fileQueue.bind(_this));
        },
        _fileDequeued: function () {
            var _this = this;
            this.uploader.on('fileDequeued', function (file) {
                _this.fileCount--;
                _this.fileSize -= file.size;
                if (!_this.fileCount) {
                    _this._setState('pedding');
                }
                _this._removeFile(file);
                _this._updateTotalProgress();
            });
        },
        _uploadAll: function () {
            var _this = this;
            this.uploader.on('all', function (type) {
                if (type == 'uploadFinished') {
                    _this._setState('confirm');
                } else if (type == 'startUpload') {
                    _this._setState('uploading');
                } else if (type == 'stopUpload') {
                    _this._setState('paused');
                }
            });
        },
        _uploadBeforeSend: function () {
            this.uploader.on('uploadBeforeSend', function (block, data) {
                //todo
            });
        },
        _uploadSuccess: function () {
            var _this = this;
            this.uploader.on('uploadSuccess', function (file, response) {
                console.log(file);
                if (response.result) {
                    $(_this).find("img").each(function () {
                        var name = $(this).attr("name");
                        if (response.data.fileName == name) {
                            $(this).attr("real-src", response.data.path);
                            $(this).parents("li").attr("data-src", "server");
                            $(this).parents("li").append('<span class="success"></span>');
                        }
                    });
                } else {
                    $('#' + file.id).find(".progress").after('<p class="error">' + response.msg
                                                             + '</p>');
                }
                console.log("uploadSuccess");
                $('#' + file.id).find('p.state').text('已上传');
            });
        },
        _uploadError: function () {
            this.uploader.on('uploadError', function (file) {
                console.log(file.id + '上传出错');
            });
        },
        _uploadComplete: function () {
            this.uploader.on('uploadComplete', function (file, response) {
                $('#' + file.id).find('p.state').fadeOut();
            });
        },
        _error: function () {
            var _this = this;
            this.uploader.on("error", function (type) {
                if (type == "F_DUPLICATE") {
                    alert("系统提示请不要重复选择文件！");
                } else if (type == "Q_EXCEED_SIZE_LIMIT") {
                    alert("附件总大小不能超过" + _this.allMaxSize * _this.allMaxNum
                          + "M！");
                } else if (type == "Q_EXCEED_NUM_LIMIT") {
                    alert("超过了最大的上传数量");
                } else if (type == "F_EXCEED_SIZE") {
                    alert("单张图片不能超过" + _this.allMaxSize + "M");
                }
            });
        },
        _uploadProgress: function () {
            var _this = this;
            this.uploader.on('uploadProgress', function (file, percentage) {
                var $li = $('#' + file.id),
                    $percent = $li.find('.progess span');

                $percent.css("width", percentage * 100 + '%');
                _this._updateTotalProgress();
            });
        },
        _getUrlParams: function (arg) {
            var search = window.location.search.substr(1).split("&");
            for (var i = 0; i < search.length; i++) {
                var splitArr = search[i].split("=");
                if ($.inArray(arg, splitArr) != -1) {
                    return splitArr[1];
                }
            }
        },
        _initServerFile: function () {
            var _this = this;
            if (this.initUrl) {
                $.ajax({
                           type: 'get',
                           url: _this.initUrl,
                           data: {
                               "noticeId": _this._getUrlParams("noticeId"),
                               "noticeType": _this._getUrlParams("noticeType")
                           },
                           dataType: 'json',
                           success: function (data) {
                               console.log(data);
                               if (data.result) {
                                   var picturesName = data.data.pictures.split(",");
                                   var data = data.data.pictureList;
                                   var len = data.length;
                                   for (var i = 0; i < len; i++) {
                                       var obj = {};
                                       obj.path = data[i];
                                       obj.name = picturesName[i];
                                       obj.src = "server";
                                       obj.id = "SVR_FILE_" + i;
                                       obj.rotation = 0;
                                       _this._fileQueue(obj);
                                   }
                               }
                           }
                       });
            }
        },
        _fileQueue: function (file) {
            file.src = file.src || "client";
            this.fileCount++;
            console.log(this.fileCount);
            this.fileSize += file.size;
            if (this.fileCount == 1) {
                this.$placeHolder.addClass('element-invisible');
                this.$statusBar.show();
            }
            this._addFile(file);
            this._setState('ready');
            this._updateTotalProgress();
        },
        _setState: function (val) {
            var file;
            var stats;
            if (val == this.state) {
                return;
            }
            this.$upload.removeClass('state-' + this.state);
            this.$upload.addClass('state-' + val);
            this.state = val;
            switch (this.state) {
                case 'pedding':
                    this.$placeHolder.removeClass('element-invisible');
                    this.$queue.parent().removeClass('filled');
                    this.$queue.hide();
                    this.$statusBar.addClass('element-invisible');
                    this.uploader.refresh();
                    break;
                case 'ready':
                    this.$placeHolder.addClass('element-invisible');
                    $('#filePicker2').removeClass('element-invisible');
                    this.$queue.parent().addClass('filled');
                    this.$queue.show();
                    this.$statusBar.removeClass('element-invisible');
                    this.uploader.refresh();
                    break;
                case 'uploading':
                    $('filePicker2').addClass('element-invisible');
                    this.$progress.show();
                    this.$upload.text('暂停上传');
                    break;
                case 'paused':
                    this.$progress.show();
                    this.$upload.text('继续上传');
                    break;
                case 'confirm':
                    this.$progress.hide();
                    this.$upload.text('开始上传').addClass('disabled');
                    stats = this.uploader.getStats();
                    if (stats.successNum && !stats.uploadFailNum) {
                        this._setState('finish');
                        return;
                    }
                    break;
                case 'finish':
                    stats = this.uploader.getStats();
                    if (stats.successNum) {
                        this.$upload.removeClass('disabled');
                        var $liStateComplete = $(".state-complete");
                        var $stateCompleteBtns = $('<div class="file-panel">' +
                                                   '<span class="cancel">删除</span>').appendTo($liStateComplete);
                        this._attachMouseEnter($liStateComplete);
                        this._attachMouseLeave($liStateComplete);
                        this._removeBind({"file": file, "btn": $stateCompleteBtns});
                        /*this._removeBind(file, $stateCompleteBtns);*/
                    } else {
                        state = 'done';
                        location.reload();
                    }
                    break;
            }
            this._updateStatus();
        },
        _addFile: function (file) {
            var _this = this;
            var index = this.$queue.find('li').length;
            var imgLeft = index * (this.thumbnailWidth + 10);
            var imgTop = 0;
            var wrapHeight = this.thumbnailHeight + 20;
            var wrapWidth = this.$queue.width() + 20 + 10;
            if (wrapWidth - imgLeft < 230) {
                imgTop = parseInt(index / 4) * (this.thumbnailHeight + 10);
                wrapHeight = imgTop + wrapHeight;
                imgLeft =
                (index % (parseInt(wrapWidth / (this.thumbnailWidth + 10)) ) )
                * (this.thumbnailWidth + 10);

            }
            this.$queue.height(wrapHeight);
            var $li = $('<li data-src="' + file.src + '" data-sort="'
                        + index + '" draggable="true" id="' + file.id
                        + '" style="position:absolute;margin:0;cursor:move;width:'
                        + this.thumbnailWidth
                        + 'px;height:' + this.thumbnailHeight + 'px;left:' + imgLeft + 'px;top:'
                        + imgTop
                        + 'px">' +
                        '<p class="imgWrap"></p>' +
                        '<p class="progress"><span></span></p>' + '</li>'
            );
            var $btns = $('<div class="file-panel">' +
                          '<span class="cancel">删除</span>').appendTo($li);
            var $progress = $li.find('p.progress span');
            var $wrap = $li.find('p.imgWrap');
            var $infoError = $('<p class="error"></p>');
            if (file.src == "client") {
                if (file.getStatus() == 'invalid') {
                    $infoError.text(this._showError(file.statusText)).appendTo($li);
                } else {
                    $wrap.text('预览中');
                    this.uploader.makeThumb(file, function (error, src) {
                        if (error) {
                            $wrap.text('不能预览');
                            return;
                        }
                        var img = $('<img draggable="true" real-src="" name="' + file.name
                                    + '" src="' + src
                                    + '">');
                        img.bind('load', function () {
                            _this._setDragEvent($(this));
                        });
                        $wrap.empty().append(img);
                    }, _this.thumbnailWidth, _this.thumbnailHeight);

                    this.percentages[file.id] = [this.fileSize, 0];
                    file.rotation = 0;
                }
                file.on('statuschange', function (cur, prev) {
                    if (prev == 'progress') {
                        $progress.hide().width(0);
                    } else if (prev == 'queued') {
                        console.log("queued");
                        $li.off('mouseenter mouseleave');
                        $btns.remove();
                    }

                    if (cur == 'error' || cur == 'invalid') {
                        $infoError.text(_this._showError(file.statusText)).appendTo($li);
                        _this.percentages[file.id][1] = 1;
                    } else if (cur == 'interrupt') {
                        $infoError.text(_this._showError('interrupt')).appendTo($li);
                    } else if (cur == 'queued') {
                        _this.percentages[file.id][1] = 0;
                    } else if (cur == 'progress') {
                        $infoError.remove();
                        $progress.css('display', 'block');
                    } else if (cur == 'complete') {
                        console.log('complete');
                        /*$li.append('<span class="success"></span>');*/
                    }
                    $li.removeClass('state-' + prev).addClass('state-' + cur);
                });
            } else {
                var img = $('<img draggable="true" style="height:250px;" real-src="' + file.path
                            + '" name="' + file.name
                            + '" src="' + file.path
                            + '">');
                img.bind('load', function () {
                    _this._setDragEvent($(this));
                });
                $wrap.empty().append(img);
            }
            $li.appendTo(this.$queue);
            this._attachMouseEnter($li);
            this._attachMouseLeave($li);
            /*this._removeBind(file, $btns);*/
            this._removeBind({"file": file, btn: $btns});

        },
        _setDragEvent: function (target) {
            var _this = this;
            target.on('drop', function (e) {
                var $from = $(origin).parents('li');
                var $to = $(e.target).parents('li');
                var origin_pos = $from.position();
                var target_pos = $to.position();
                var from_sort = $from.attr('data-sort');
                var to_sort = $to.attr('data-sort');

                $from.addClass('move').animate(target_pos, "fast", function () {
                    $(this).removeClass('move');
                }).attr('data-sort', to_sort);

                $to.addClass('move').animate(origin_pos, 'fast', function () {
                    $(this).removeClass('move');
                }).attr('data-sort', from_sort);
            }).on('dragstart', function (e) {
                if (_this.is_moveing) {
                    return false;
                }
                _this.is_moveing = true;
                e.originalEvent.dataTransfer.effectAllowd = 'move';
                origin = this;
            }).on('dragover', function (e) {
                if (e.preventDefault) {
                    e.preventDefault();
                }
                _this.is_moveing = false;
                e.originalEvent.dataTransfer.dropEffect = 'move';
            });
        },
        _removeBind: function (obj) {
            var _this = this;
            (function (obj) {
                obj.btn.on('click', 'span', function () {
                    console.log(obj.file);
                    console.log(obj.btn);
                    var index = $(this).index(), deg;
                    if (!obj.file) {
                        console.log("没有file");
                        var file = {};
                        file.id = $(this).parents("li").attr("id");
                        file.src = $(this).parents("li").attr("data-src");
                        file.name =
                        $(this).parents("li").find(".imgWrap img").attr("name");
                    } else {
                        var file;
                        /*obj.file.setStatus = _this._getStatusFunc();
                         console.log(obj.file);*/
                        file = obj.file;
                    }
                    switch (index) {
                        case 0:
                            //修改删除后面所有图片的位置
                            var allImgs = {};
                            var del_sort = parseInt($('#' + file.id).attr('data-sort'));
                            _this.$queue.find('li').each(function (index, obj) {
                                if ($(obj).attr('data-sort') > del_sort) {
                                    var sort = parseInt($(obj).attr('data-sort'));
                                    var $prevObj = $("li[data-sort=" + (sort - 1) + "]");
                                    if ($prevObj) {
                                        allImgs[$(obj).attr('id')] = $prevObj.position();
                                    }
                                }
                            });
                            for (var k in allImgs) {
                                var sort = parseInt($('#' + k).attr('data-sort'));
                                $('#' + k).attr('data-sort', sort - 1).css({
                                                                               left: allImgs[k].left
                                                                                     + 'px',
                                                                               top:  allImgs[k].top
                                                                                     + 'px'
                                                                           });
                            }
                            allImgs = null;
                            if (file.src == "client") {
                                _this.uploader.removeFile(file.id);
                            } else {
                                if (!obj.file) {
                                    _this.uploader.removeFile(file.id);
                                } else {
                                    _this.uploader.removeFile(file);
                                }
                                _this._removeServerFile(file);
                                $('#' + file.id).remove();
                            }
                            return;
                        case 1:
                            file.rotation += 90;
                            break;
                        case 2:
                            file.rotation -= 90;
                            break;
                    }

                    if (supportTransition) {
                        deb = 'rotate(' + file.rotation + 'deg)';
                        $(this).css({
                                        '-webkit-transform': deb,
                                        '-mos-transform': deg,
                                        '-o-transform': deg,
                                        'transform': deg
                                    });
                    } else {
                    }
                });
            })(obj);
        },
        _updateStatus: function () {
            var text = '', stats;
            if (this.state == 'ready') {
                text = '选中' + this.fileCount + '张图片';
            } else if (this.state == 'confirm') {
                stats = this.uploader.getStats();//todo
                if (stats.uploadFailNum) {
                    text =
                    '已成功上传' + stats.successNum + '张照片' + stats.uploadFailNum
                    + '张照片上传失败,<a class="retry" href="#">重新上传</a>失败图片或<a class="ignore" href="#">忽略</a>';//todo
                }
            } else {
                stats = this.uploader.getStats();
                text =
                '共' + this.fileCount + '张';
                if (stats.uploadFailNum) {
                    text += ',失败' + stats.uploadFailNum + '张';
                }
            }
            this.$info.html(text);
        },
        _updateTotalProgress: function () {
            var loaded = 0,
                total = 0,
                spans = this.$progress.children(),
                percent;

            $.each(this.percentages, function (k, v) {
                total += v[0];
                loaded += v[0] * v[1];
            });

            percent = total ? loaded / total : 0;

            spans.eq(0).text(Math.round(percent * 100) + '%');
            spans.eq(1).css('width', Math.round(percent * 100) + '%');
            this._updateStatus();
        },
        _removeFile: function (file) {
            var $li = $('#' + file.id);
            delete this.percentages[file.id];
            this._updateTotalProgress();
            $li.off().find('.file-panel').off().end().remove();
        },
        _removeServerFile: function (file) {
            var _this = this;
            $.ajax({
                       type: 'post',
                       url: _this.removeUrl,
                       data: {
                           "noticeId": _this.getUrlParams("noticeId"),
                           "noticeType": _this.getUrlParams("noticeType"),
                           "pictureName": file.name
                       },
                       dataType: 'json',
                       success: function (data) {
                           if (data.result) {
                               _this._updateStatus();
                           }
                       }
                   });
        },
        _attachMouseEnter: function (target) {
            target.on('mouseenter', function () {
                $(this).find(".file-panel").stop().animate({height: 30});
            });
        },
        _attachMouseLeave: function (target) {
            target.on('mouseleave', function () {
                $(this).find(".file-panel").stop().animate({height: 0})
            });
        },
        _showError: function (code) {
            switch (code) {
                case 'exceed_size':
                    text = '文本大小超出最大' + allMaxSize + 'M';
                    break;
                case 'interrupt':
                    text = '上传暂停';
                    break;
                default:
                    text = '上传失败';
                    break;
            }
            return text;
        }

    };
    $.fn[pluginName] = function (opts) {
        $.extend(this, _PROTOTYPE_, opts);
        this._init();
    }
}, "fileWebUploader");

